package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.constant.SizeConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.PaasFormDataEsInitDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.OpportunityModel;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.existsQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * 描述信息
 *
 * @ClassName FixInnerDataController
 * @Author 梁鲁江
 * 创建时间 2020/12/3 20:01
 * 修改时间  2020/12/3 20:01
 **/
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/fixInner")
public class FixInnerDataController {
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private PaasFormModel paasFormModel;

    @Resource
    private ProBaseConfig proBaseConfig;
    private static final Logger LOG = LoggerFactory.getLogger(FixInnerDataController.class);
    @RequestMapping(value = "/exists", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public String exists(@RequestBody @Valid PaasFormDataEsInitDTO paasFormDataEsInitDTO, BindingResult br) {
        XbbResponse<String> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                if(!proBaseConfig.getXbbCode().equals(paasFormDataEsInitDTO.getXbbCode())){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
                }
                for (IndexTypeEnum value : IndexTypeEnum.getAllEnum()) {
                    try {
                        IndexTypeEnum indexTypeEnum = value;
                        if("my_team".equals(value.getType()) || "product_warehouse".equals(value.getType()) || "product_stock_info".equals(value.getType())
                                || "call_center_call_log".equals(value.getType())  ||  "contract_performance".equals(value.getType())  || "my_cc".equals(value.getType())
                                || "my_evaluation".equals(value.getType()) ||"my_product".equals(value.getType())||"my_product".equals(value.getType())
                                || IndexTypeEnum.IDX_PAYMENT_BALANCE.getType().equals(value.getType()) || IndexTypeEnum.UNKNOWN.getType().equals(value.getType())
                                || IndexTypeEnum.IDX_PAY_BALANCE.getType().equals(value.getType()) || IndexTypeEnum.IDX_PAY_BALANCE_TEAM.getType().equals(value.getType())
                        ){
                            continue;
                        }
                        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                        BoolQueryBuilder boolQueryBuilder = boolQuery();
                        PaasFormDataEntityExt ps = new PaasFormDataEntityExt();
                        Class<?> clazz = ps.getClass();
                        List<Field> fieldList = new ArrayList<>();
                        Field[] fields;
                        while (clazz != null){
                            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
                            clazz = clazz.getSuperclass();
                        }
                        fields = new Field[fieldList.size()];
                        fieldList.toArray(fields);
                        Set<String> stringSet = new HashSet<>();
                        for (Field field : fieldList) {
                            stringSet.add(field.getName());
                        }
                        StringBuffer stringBuffer = new StringBuffer();
                        if(Objects.equals(indexTypeEnum.getIndex(),IndexTypeEnum.IDX_SAAS_CUSTOMER.getIndex())){
                            stringSet.add("customerId");
                        }
                        for (String s : stringSet) {
                            boolQueryBuilder.should(existsQuery("data."+s));
                            stringBuffer.append("'$.");
                            stringBuffer.append(s);
                            stringBuffer.append("',");
                        }
                        boolQueryBuilder.minimumShouldMatch(1);
                        sourceBuilder.query(boolQueryBuilder);
                        sourceBuilder.fetchSource("id",null);
                        //分页
                        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, SizeConstant.PAGE_SIZE);
                        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex()).types(indexTypeEnum.getType());
                        searchRequest.source(sourceBuilder);
                        List<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.findScrollList(PaasFormDataEntityExt.class, searchRequest, SizeConstant.SCROLL_TIME_IN_MILLIS);
                        Set setId = new HashSet();
                        for (PaasFormDataEntityExt esEntity : esEntities) {
                            setId.add(esEntity.getId());
                        }
                        LOG.error(indexTypeEnum.getIndex()+"___"+indexTypeEnum.getType()+"=============="+setId);
                    } catch (Exception e) {
                        LOG.error("",e);
                    }
                }
                response = new XbbResponse<>("");
            } catch (Exception e) {
                response = new XbbResponse<>("");
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }



    /**
     * @Author mingliang
     * @Description 销售机会更新最后跟进时间
     * @Date 2022/8/16 11:16
     * @param paasFormDataEsInitDTO
     * @param br
     **/
    @RequestMapping(value = "/salesOpportunity/updateDate2", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public String salesOpportunityUpdate(@RequestBody @Valid PaasFormDataEsInitDTO paasFormDataEsInitDTO, BindingResult br) throws XbbException {
        XbbResponse<String> response;
        if (!proBaseConfig.getXbbCode().equals(paasFormDataEsInitDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        String corpid = paasFormDataEsInitDTO.getCorpid();
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(), corpid);
        if (Objects.isNull(paasFormEntityExt)) {
            return "";
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("formId", paasFormDataEsInitDTO.getFormId()));
        boolQueryBuilder.filter(termQuery("my_join_field", IndexTypeEnum.IDX_SAAS_OPPORTUNITY.getType()));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery("flowStatus", Arrays.asList(0, 2)));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OPPORTUNITY.getIndex());
        searchRequest.source(sourceBuilder);
        CountRequest countRequest = new CountRequest(searchRequest.indices()[0]);
        countRequest.query(searchRequest.source().query());
        long count = xbbElasticsearchRestTemplate.count(countRequest);
        int countInt = (int) count;
        int pageSize = 1000;
        int pageNum = (int) (countInt % pageSize > 0 ? countInt / pageSize + 1 : countInt / pageSize);
        for (int currentPage = 1; currentPage <= pageNum; currentPage++) {
            int startIndex = (currentPage - 1) * pageSize;
            PageRequest pageRequest = EsUtil.setPage(sourceBuilder, startIndex, pageSize);
            searchRequest.source(sourceBuilder);
            XbbAggregatedPage<PaasFormDataEntityExt> opportunityList = xbbElasticsearchRestTemplate.queryForPagesWithoutCount(pageRequest, searchRequest, PaasFormDataEntityExt.class);
            if (Objects.nonNull(opportunityList) && CollectionsUtil.isNotEmpty(opportunityList.getContent())) {
                List<PaasFormDataEntityExt> content = opportunityList.getContent();
                if (CollectionsUtil.isNotEmpty(content)) {
                    List<UpdateDataEntity> updateList = new ArrayList<>();
                    for (int n = 0; n < content.size(); n++) {
                        PaasFormDataEntityExt paasFormDataEntityExt = content.get(n);
                        JSONObject data = paasFormDataEntityExt.getData();
                        if (Objects.isNull(data)) {
                            continue;
                        }
                        Long date_2 = data.getLong("date_2");
                        //查询出跟进记录
                        SearchRequest communicateSearchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE.getIndex());
                        SearchSourceBuilder communicateSourceBuilder = new SearchSourceBuilder();
                        BoolQueryBuilder communicateBoolQueryBuilder = boolQuery();
                        communicateBoolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                        communicateBoolQueryBuilder.filter(termQuery("formId", paasFormEntityExt.getId()));
                        communicateBoolQueryBuilder.filter(termQuery("my_join_field", IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE.getType()));
                        communicateBoolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
                        communicateBoolQueryBuilder.filter(termQuery("data.text_1.keyword", paasFormDataEntityExt.getData().getString("text_3")));
                        communicateBoolQueryBuilder.filter(termQuery("logType", 0));
                        communicateBoolQueryBuilder.filter(termQuery("data.text_5.keyword", String.valueOf(paasFormDataEntityExt.getDataId())));
                        communicateSourceBuilder.from(0);
                        communicateSourceBuilder.size(1);
                        communicateSourceBuilder.sort("data.date_1", SortOrder.DESC);
                        communicateSourceBuilder.query(communicateBoolQueryBuilder);
                        communicateSearchRequest.source(communicateSourceBuilder);
                        List<PaasFormDataEntityExt> paasFormDataEntityExtList = xbbElasticsearchRestTemplate.queryForList(communicateSearchRequest, PaasFormDataEntityExt.class);
                        if (CollectionsUtil.isEmpty(paasFormDataEntityExtList)) {
                            continue;
                        }
                        PaasFormDataEntityExt communicateEntity = paasFormDataEntityExtList.get(0);
                        Long communicateTime = communicateEntity.getData().getLong("date_1");

                        if ((Objects.nonNull(communicateTime) && Objects.nonNull(date_2) && communicateTime.longValue() > date_2.longValue()) || (Objects.isNull(date_2) && Objects.nonNull(communicateTime))) {
                            UpdateDataEntity updateDataEntity = new UpdateDataEntity();
                            updateDataEntity.setId(paasFormDataEntityExt.getDataId());
                            JSONObject dataTemp = paasFormDataEntityExt.getData();
                            dataTemp.put("date_2", communicateTime);
                            UpdateDataEntity updateData = ExplainUtil.getUpdateData(paasFormDataEntityExt.getDataId(), dataTemp, corpid);
                            updateList.add(updateData);
                        }
                    }
                    if (CollectionsUtil.isNotEmpty(updateList)) {
                        opportunityModel.updateBatch(updateList, corpid);
                    }
                }
            }
        }
        response = new XbbResponse<>("");
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    private JSONObject getSourceAsMapByCommunicateJSONObject(JSONObject communicateJSONObject) {
        JSONObject aggregations = communicateJSONObject.getJSONObject("aggregations");
        if (Objects.isNull(aggregations)) {
            return null;
        }
        JSONObject asMap = aggregations.getJSONObject("asMap");
        if (Objects.isNull(asMap)) {
            return null;
        }
        JSONObject latestRecord = asMap.getJSONObject("latestRecord");
        if (Objects.isNull(latestRecord)) {
            return null;
        }
        JSONObject hits = latestRecord.getJSONObject("hits");
        if (Objects.isNull(hits)) {
            return null;
        }
        JSONArray hitsList = hits.getJSONArray("hits");
        if (Objects.isNull(hitsList)) {
            return null;
        }
        return hitsList.getJSONObject(0).getJSONObject("sourceAsMap");
    }


}

